package com.zyk.scaffold.core.context;

import com.alibaba.fastjson.JSON;
import com.zyk.scaffold.common.utils.AssertUtil;
import com.zyk.scaffold.common.utils.StringUtils;
import com.zyk.scaffold.common.utils.jwt.JwtUtil;
import com.zyk.scaffold.common.utils.jwt.Payload;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;

import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;

@Slf4j
public class JwtHelper implements EnvironmentAware {
    private static final String PUBLIC_KEY_DEFAULT = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxacWDUA76b01Zdr+Ffa9ZXSUlZ2cWtPZLYWFs9UoQuoskDpc6nEX8cyYoP824wXyMViFymkYlGJ0TVk71YpLISQdRLuUS2Y/rgKYTS8TqfrkTLhFl6BY0gXifcZjLWJddYeo6cMpHBo4VEcNu6DTAFsrzZaf/a4sScggZzn9fYqhUjcY72r3jZFAqhh63GXoOTRoVYQooITdun6UVL/LAKLSJEw2rtotZXbffZOtJkuN9YqW7I+QSEUEF8BPGudWcW5rcerteZzfNSznBSfydbsIrlWTCNp7Do/QBd9hMxJ6K4FrysrrOAL26foFbdnw518MVx+jTCvD6/fpsDfmRwIDAQAB";
    private static final String PRIVATE_KEY_DEFAULT = "MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDFpxYNQDvpvTVl2v4V9r1ldJSVnZxa09kthYWz1ShC6iyQOlzqcRfxzJig/zbjBfIxWIXKaRiUYnRNWTvVikshJB1Eu5RLZj+uAphNLxOp+uRMuEWXoFjSBeJ9xmMtYl11h6jpwykcGjhURw27oNMAWyvNlp/9rixJyCBnOf19iqFSNxjvaveNkUCqGHrcZeg5NGhVhCighN26fpRUv8sAotIkTDau2i1ldt99k60mS431ipbsj5BIRQQXwE8a51Zxbmtx6u15nN81LOcFJ/J1uwiuVZMI2nsOj9AF32EzEnorgWvKyus4Avbp+gVt2fDnXwxXH6NMK8Pr9+mwN+ZHAgMBAAECggEBALZhVCbMA7zNu40OAvDPabpJVaWs9o6U9sxbbaEf6nO8U3yObhhiXN7glGHSvZnEbdP8xA+e5HBfXMPWuDB12JdvFJbMo6zjX5U4jcKC0xlBChKE4qpj6jF5/qFiQzeokWaW1FVHoRJuW1Xg7poYbzrf5c5h06WoZvN59/RofTCt7navqEyOoTbAJJSAuOyC30OgS5JSd0lnMCS9HbVSmKJKd+97uH4xIcv4VCWIBXKENAhuFLae8nNpQUW+yP+kVZ9p7jnRzqy/T9xnjaqvuqsTLKLkxrKSOcSdLi45G3TgyO4GrBYLGlfeIEK/YX9xtgALrdPUSdDTMAR3KV+j6KkCgYEA+flS4D5cm/AQ46rjqbv+gX2DpXGEMtO6ln1L6ciPN1Bkxhs5DK81j5AZqTH+MB3FyPceKtUDb7+zKtwLYXL4jj4vdn5ePaW2zWLp3uLNze8Bn6tYBmPvPfZee8Rx2RTi71HQgCK8s2RCm7gsXEO9YBkwJJWKPZ2dm/DLoknNwsUCgYEAymreqcdofoANmOZGcUm9GMmjBf6DR1IxIvSvScs3zaa0Tq9EWLjKvvENtdhRsCTQq8x/8yb6qqOSJ5qtHWFd1k+RjMikCAasQuuXlUNClCNNQUcW9Zg1/AeKBHtO9/uXGAO7zt8LlD+hc+AMGdFDJ4uqtWHPHYze91im3PNSpZsCgYEA5pYM0vnzp4zNp5WtqJbX8E79rxGFpvUUe1ldO2xcX+Py8aOO/ppox+NfKGoLVgtAtV7vHwebweuNtI2CmgPaMCxA0AdFm4xPkioaHhYNTleYodcGve5VdEzdX0IY2uyfYa+Qq4JfmwNzRf2gPgPmnszdUgH3oVrRVlXLIgr+mRkCgYEAmvxhKRYqCFH8F0qaPTv8sfISBRDva7ifLuizHomfXLN785N3fYdglfr0SHwtb/WAYUrf3UnHPMipq/FfA9P9iY67H1SxZAPX+hVxpzQs0kiFaqoIBlxZWXRcVTolKPNWqWiScL+Pmh9ue87c9Repl6n1N5SAhVvLjRAwE5WrfmkCgYEAukHDzGDAIYmKEm5ZGvIAdqAihrTAsnr3o6vw3rAzPqkziusQbQ73U/wzwqICNPzNREm6EEBfJ/ogHBxtQMH6ujkD/8qQduVB0kesSrJ7MDmJgsaebGik1YsN+6+cN5Teuu4THqFQU5zC66nUKIGw4tDHyKh8ffDYc7HcaDHidlc=";

    private static PublicKey PUBLIC_KEY = null;
    private static PrivateKey PRIVATE_KEY = null;


    private static final String ENVIRONMENT_PROPERTY_PUBLIC_KEY = "local.oauth.jwt.publickey";
    private static final String ENVIRONMENT_PROPERTY_PRIVATE_KEY = "local.oauth.jwt.privatekey";

    @Override
    public void setEnvironment(Environment environment) {
        String publicKeyStr = environment.getProperty(ENVIRONMENT_PROPERTY_PUBLIC_KEY);
        String privateKeyStr = environment.getProperty(ENVIRONMENT_PROPERTY_PRIVATE_KEY);
        try {
            PUBLIC_KEY = buildPublicKey(publicKeyStr);
            PRIVATE_KEY = buildPrivateKey(privateKeyStr);
        } catch (Exception ex) {
            log.error("公钥、密钥对象创建失败,请检查配置！", ex);
        }
    }

    private static PublicKey buildPublicKey(String publicKeyStr) throws InvalidKeySpecException, NoSuchAlgorithmException {
        if(StringUtils.isEmpty(publicKeyStr)) {
            return JwtUtil.toPublicKey(PUBLIC_KEY_DEFAULT);
        }
        return JwtUtil.toPublicKey(publicKeyStr);
    }

    private static PrivateKey buildPrivateKey(String privateKeyStr) throws InvalidKeySpecException, NoSuchAlgorithmException {
        if(StringUtils.isEmpty(privateKeyStr)) {
            return JwtUtil.toPrivateKey(PRIVATE_KEY_DEFAULT);
        }
        return JwtUtil.toPrivateKey(privateKeyStr);
    }

    public static UserContext getUserContext(String jwt){
        AssertUtil.notIsNull(PUBLIC_KEY, "公钥未初始化");
        AssertUtil.notIsNull(jwt, "jwt不能为空");
        Payload payload = JwtUtil.parserJwtPayload(jwt, PUBLIC_KEY);
        return JSON.parseObject(payload.getJson(), UserContext.class);
    }

    public static AppContext getAppContext(String jwt) {
        AssertUtil.notIsNull(PUBLIC_KEY, "公钥未初始化");
        AssertUtil.notIsNull(jwt, "jwt不能为空");
        Payload payload = JwtUtil.parserJwtPayload(jwt, PUBLIC_KEY);
        return JSON.parseObject(payload.getJson(), AppContext.class);
    }

    public static Payload getPayload(String jwt) {
        AssertUtil.notIsNull(PUBLIC_KEY, "公钥未初始化");
        AssertUtil.notIsNull(jwt, "jwt不能为空");
        Payload payload = JwtUtil.parserJwtPayload(jwt, PUBLIC_KEY);
        return payload;
    }

    public static String toJwt(Payload payload){
        AssertUtil.notIsNull(PRIVATE_KEY, "私钥未初始化");
        AssertUtil.notIsNull(payload, "payload不能为空");
        return JwtUtil.creatJwt(payload.getJson(), PRIVATE_KEY, payload.getExpire());
    }

    public static String toJwt(AppContext appContext){
        AssertUtil.notIsNull(PRIVATE_KEY, "私钥未初始化");
        AssertUtil.notIsNull(appContext, "app上下文不能为空");
        return JwtUtil.creatJwt(JSON.toJSONString(appContext), PRIVATE_KEY, appContext.getExpire());
    }

    public static String toJwt(UserContext userContext){
        AssertUtil.notIsNull(PRIVATE_KEY, "私钥未初始化");
        AssertUtil.notIsNull(userContext, "用户上下文不能为空");
        return JwtUtil.creatJwt(JSON.toJSONString(userContext), PRIVATE_KEY, userContext.getExpire());
    }
}
